package com.tfswx.jkgl.designer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.tfswx.jkgl.core.cscl.JmfsUtil;
import com.tfswx.jkgl.core.cscl.base.CsclBase;
import com.tfswx.jkgl.core.exception.AppException;
import com.tfswx.jkgl.core.sjcc.ScclBase;
import com.tfswx.jkgl.core.sjcc.ScclUtil;
import com.tfswx.jkgl.core.yzfs.YzfsUtil;
import com.tfswx.jkgl.core.yzfs.base.YzfsBase;
import com.tfswx.jkgl.designer.dao.*;
import com.tfswx.jkgl.designer.datasource.DynamicDataSourceContextHolder;
import com.tfswx.jkgl.designer.dto.SjkjgDTO;
import com.tfswx.jkgl.designer.dto.mxgl.MxdyAddInputDTO;
import com.tfswx.jkgl.designer.dto.stgl.*;
import com.tfswx.jkgl.designer.dto.xmgl.MkxxQueryResult;
import com.tfswx.jkgl.designer.enums.ZdlxEnum;
import com.tfswx.jkgl.designer.model.*;
import com.tfswx.jkgl.designer.query.*;
import com.tfswx.jkgl.designer.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author ricky
 * @date 2021/12/10
 */
@Service
public class StglServiceImpl implements StglService {
    @Resource
    private SjmxXtStdyMapper stdyMapper;
    @Resource
    private SjmxXtZddyMapper zddyMapper;
    @Resource
    private XmglXtXmxxMapper xmxxMapper;
    @Resource
    private XmglXtMkxxMapper mkxxMapper;
    @Resource
    private SjkjgMapper sjkjgMapper;
    @Resource
    private MxglService mxglService;

    @Override
    public String addStdy(StdyAddInputDTO inputDTO) {
        SjmxXtStdy sjmxXtStdy = BeanUtil.copyProperties(inputDTO, SjmxXtStdy.class);
        sjmxXtStdy.setStbm(IdUtil.fastSimpleUUID().toUpperCase());
        sjmxXtStdy.setXh(System.currentTimeMillis());
        sjmxXtStdy.setSfsc("N");
        sjmxXtStdy.setCjsj(new Date());
        sjmxXtStdy.setZhxgsj(new Date());
        int i = stdyMapper.insert(sjmxXtStdy);
        if (i != 1) {
            throw new RuntimeException("添加实体信息失败");
        }
        return sjmxXtStdy.getStbm();
    }

    @Override
    public boolean deleteStdy(StdyDeleteInputDTO inputDTO) {
        SjmxXtStdy sjmxXtStdy = BeanUtil.copyProperties(inputDTO, SjmxXtStdy.class);
        sjmxXtStdy.setZhxgsj(new Date());
        int i = stdyMapper.delete(sjmxXtStdy);
        if (i != 1) {
            throw new RuntimeException("删除实体信息失败");
        }
        return false;
    }

    @Override
    public boolean updateStdy(StdyUpdateInputDTO inputDTO) {
        SjmxXtStdy sjmxXtStdy = BeanUtil.copyProperties(inputDTO, SjmxXtStdy.class);
        sjmxXtStdy.setZhxgsj(new Date());
        int i = stdyMapper.update(sjmxXtStdy);
        if (i != 1) {
            throw new RuntimeException("修改实体信息失败");
        }
        return true;
    }

    @Override
    public List<StdyQueryOutputDTO> queryStdy(StdyQueryInputDTO inputDTO) {
        SjmxXtStdy sjmxXtStdy = BeanUtil.copyProperties(inputDTO, SjmxXtStdy.class);
        return stdyMapper.queryStdy(sjmxXtStdy);
    }

    @Override
    public String addZddy(ZddyAddInputDTO inputDTO) {
        SjmxXtZddy sjmxXtZddy = BeanUtil.copyProperties(inputDTO, SjmxXtZddy.class);
        sjmxXtZddy.setXh(System.currentTimeMillis());
        sjmxXtZddy.setSfsc("N");
        sjmxXtZddy.setCjsj(new Date());
        sjmxXtZddy.setZhxgsj(new Date());
        SjmxXtZddy temp = zddyMapper.getZddy(sjmxXtZddy);
        if (temp != null) {
            // 存在
            if ("Y".equals(temp.getSfsc())) {
                // 已删除
                // 取消删除
                zddyMapper.undelete(sjmxXtZddy);
                // 更新
                zddyMapper.update(sjmxXtZddy);
            } else {
                throw new AppException("字段【" + inputDTO.getZdmc() + "】已存在，请勿重复添加！");
            }
        } else {
            int i = zddyMapper.insert(sjmxXtZddy);
            if (i != 1) {
                throw new RuntimeException("添加字段信息失败");
            }
        }
        return sjmxXtZddy.getStbm();
    }

    @Override
    public boolean deleteZddy(ZddyDeleteInputDTO inputDTO) {
        SjmxXtZddy sjmxXtZddy = BeanUtil.copyProperties(inputDTO, SjmxXtZddy.class);
        sjmxXtZddy.setZhxgsj(new Date());
        int i = zddyMapper.delete(sjmxXtZddy);
        if (i != 1) {
            throw new RuntimeException("删除字段信息失败");
        }
        return false;
    }

    @Override
    public boolean updateZddy(ZddyUpdateInputDTO inputDTO) {
        SjmxXtZddy sjmxXtZddy = BeanUtil.copyProperties(inputDTO, SjmxXtZddy.class);
        sjmxXtZddy.setZhxgsj(new Date());
        int i = zddyMapper.update(sjmxXtZddy);
        if (i != 1) {
            throw new RuntimeException("修改字段信息失败");
        }
        return true;
    }

    @Override
    public List<ZddyQueryOutputDTO> queryZddy(ZddyQueryInputDTO inputDTO) {
        SjmxXtZddy sjmxXtZddy = BeanUtil.copyProperties(inputDTO, SjmxXtZddy.class);
        return zddyMapper.queryZddy(sjmxXtZddy);
    }

    /**
     * 查询字段策略
     *
     * @return
     */
    @Override
    public ZdclQueryOutputDTO queryZdcl() {
        ZdclQueryOutputDTO res = new ZdclQueryOutputDTO();

        List<ZdclQueryOutputDTO.ClOutputDTO> yzfsList = new ArrayList<>();
        List<ZdclQueryOutputDTO.ClOutputDTO> jmfsclList = new ArrayList<>();
        List<ZdclQueryOutputDTO.ClOutputDTO> scclList = new ArrayList<>();
        Map<String, YzfsBase> yzfsMap = YzfsUtil.getYzfsMap();
        if (yzfsMap != null) {
            yzfsMap.forEach((key, value) -> yzfsList.add(new ZdclQueryOutputDTO.ClOutputDTO(key, value.getName(), value.sfxycs())));
        }
        res.setYzfs(yzfsList);

        Map<String, CsclBase> jmfsMap = JmfsUtil.getJmfsMap();
        if (jmfsMap != null) {
            jmfsMap.forEach((key, value) -> jmfsclList.add(new ZdclQueryOutputDTO.ClOutputDTO(key, value.getName(), value.sfxycs())));
        }
        res.setJmfs(jmfsclList);

        Map<String, ScclBase> scclMap = ScclUtil.getScclMap();
        if (scclMap != null) {
            scclMap.forEach((key, value) -> scclList.add(new ZdclQueryOutputDTO.ClOutputDTO(key, value.getName(), value.sfxycs())));
        }
        res.setSccl(scclList);
        return res;
    }

    private static List<String> XTZDS = Arrays.asList("SFSC", "CJSJ", "ZHXGSJ", "sfsc", "cjsj", "zhxgsj");
    @Resource
    private PlatformTransactionManager platformTransactionManager;

    @Resource
    private TransactionDefinition transactionDefinition;

    @Override
    public void scStdyhzddy(StdyhzddyScInputDTO inputDTO) {
        XmglXtXmxx xmglXtXmxx = new XmglXtXmxx();
        xmglXtXmxx.setXmbm(inputDTO.getXmbm());
        xmglXtXmxx = xmxxMapper.get(xmglXtXmxx);
        if (xmglXtXmxx == null) {
            throw new AppException("项目不存在或已经删除");
        }
        String sjklx = xmglXtXmxx.getSjklx();

        String mkbm = inputDTO.getMkbm();
        if (StringUtils.isBlank(mkbm)) {
            XmglXtMkxx xmglXtMkxx = new XmglXtMkxx();
            xmglXtMkxx.setXmbm(inputDTO.getXmbm());
            List<MkxxQueryResult> mkxxQueryResults = mkxxMapper.queryMkxx(xmglXtMkxx);
            if (mkxxQueryResults == null || mkxxQueryResults.isEmpty()) {
                throw new AppException("项目下没有模块，请新建一个模块后重试");
            }
            mkbm = mkxxQueryResults.get(0).getMkbm();
        }
        // 查询数据库结构
        List<SjkjgDTO> sjkjglb;
        DynamicDataSourceContextHolder.setDataSourceType(inputDTO.getXmbm());
        try {
            if ("2".equals(sjklx)) {
                // mysql
                String sjkmc = inputDTO.getSjkmc();
                if (StringUtils.isBlank(sjkmc)) {
                    throw new AppException("数据库类型为mysql，sjkmc-不能为空");
                }
                MysqlJgQueryParam mysqlJgQueryParam = new MysqlJgQueryParam();
                mysqlJgQueryParam.setSjkmc(sjkmc);
                mysqlJgQueryParam.setStbmList(inputDTO.getStbmList());
                sjkjglb = sjkjgMapper.queryMysqlJg(mysqlJgQueryParam);
            } else if ("1".equals(sjklx)) {
                // 达梦
                DmJgQueryParam dmJgQueryParam = new DmJgQueryParam();
                dmJgQueryParam.setStbmList(inputDTO.getStbmList());
                sjkjglb = sjkjgMapper.queryDmJg(dmJgQueryParam);
            } else if ("3".equals(sjklx)) {
                // sqlite
                throw new AppException("暂不支持数据库类型【sqlite】");
            } else if ("4".equals(sjklx)) {
                // oracle
                throw new AppException("暂不支持数据库类型【oracle】");
            } else {
                throw new AppException("暂不支持数据库类型【未知】");
            }
            System.out.println(sjkjglb);
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
        TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
        try {
            StdyAddInputDTO stdyAddInputDTO;
            ZddyAddInputDTO zddyAddInputDTO;
            for (SjkjgDTO sjkjgDTO : sjkjglb) {
                stdyAddInputDTO = new StdyAddInputDTO();
                stdyAddInputDTO.setStmc(sjkjgDTO.getStmc());
                stdyAddInputDTO.setStms(sjkjgDTO.getStms());
                stdyAddInputDTO.setStflbm(mkbm);
                // 添加实体定义
                String stbm = addStdy(stdyAddInputDTO);
                for (SjkjgDTO.Zdxx zdxx : sjkjgDTO.getZdxxList()) {
                    zddyAddInputDTO = new ZddyAddInputDTO();
                    zddyAddInputDTO.setStbm(stbm);
                    zddyAddInputDTO.setZdmc(zdxx.getZdmc());
                    zddyAddInputDTO.setZdms(zdxx.getZdms());
                    zddyAddInputDTO.setZdlx(ZdlxEnum.valueOfName(zdxx.getZdlx()).getCode());
                    zddyAddInputDTO.setZdcd(zdxx.getZdcd());
                    zddyAddInputDTO.setZdjd(0);
                    zddyAddInputDTO.setSfzj("N");
                    // 是否不为空
                    zddyAddInputDTO.setSfwk("N");
                    zddyAddInputDTO.setZdlbbm("0000010003");
                    zddyAddInputDTO.setZdlbmc("业务类");

                    if ("PRI".equalsIgnoreCase(zdxx.getJlx())) {
                        // 主键类
                        zddyAddInputDTO.setZdlbbm("0000010001");
                        zddyAddInputDTO.setZdlbmc("主键类");
                        zddyAddInputDTO.setSfwk("Y");
                        zddyAddInputDTO.setSfzj("Y");
                        zddyAddInputDTO.setScclbm("UUID");
                        zddyAddInputDTO.setScclmc("UUID");
                        // zddyAddInputDTO.setScclcs();
                    } else if (XTZDS.contains(zdxx.getZdmc())) {
                        // 系统字段
                        zddyAddInputDTO.setZdlbbm("0000010002");
                        zddyAddInputDTO.setZdlbmc("系统类");
                    }

                    zddyAddInputDTO.setSfjm("N");
                    // zddyAddInputDTO.setSjybm();
                    // zddyAddInputDTO.setSjymc();
                    // 添加字段定义
                    addZddy(zddyAddInputDTO);
                }
                MxdyAddInputDTO mxdyAddInputDTO = new MxdyAddInputDTO();
                mxdyAddInputDTO.setMxflbm(mkbm);
                mxdyAddInputDTO.setMxmc(sjkjgDTO.getStms());
                mxdyAddInputDTO.setStmcjh(sjkjgDTO.getStmc());
                mxdyAddInputDTO.setZstmc(sjkjgDTO.getStmc());
                mxdyAddInputDTO.setMxdy("1");
                mxdyAddInputDTO.setBz(null);
                mxglService.addMxdy(mxdyAddInputDTO);
            }
            platformTransactionManager.commit(transactionStatus);
        } catch (Throwable t) {
            platformTransactionManager.rollback(transactionStatus);
            throw t;
        }
    }

    @Override
    public List<StlbQueryResult> queryStlb(StlbQueryInputDTO inputDTO) {
        XmglXtXmxx xmglXtXmxx = new XmglXtXmxx();
        xmglXtXmxx.setXmbm(inputDTO.getXmbm());
        xmglXtXmxx = xmxxMapper.get(xmglXtXmxx);
        if (xmglXtXmxx == null) {
            throw new AppException("项目不存在或已经删除");
        }
        String sjklx = xmglXtXmxx.getSjklx();

        // 查询数据库结构
        DynamicDataSourceContextHolder.setDataSourceType(inputDTO.getXmbm());
        try {
            if ("2".equals(sjklx)) {
                // mysql
                String sjkmc = inputDTO.getSjkmc();
                if (StringUtils.isBlank(sjkmc)) {
                    throw new AppException("数据库类型为mysql，sjkmc-不能为空");
                }
                MysqlStbmlbQueryParam mysqlStbmlbQueryParam = new MysqlStbmlbQueryParam();
                mysqlStbmlbQueryParam.setSjkmc(sjkmc);
                return sjkjgMapper.queryMysqlStbmlb(mysqlStbmlbQueryParam);
            } else if ("1".equals(sjklx)) {
                // 达梦
                return sjkjgMapper.queryDmStbmlb();
            } else if ("3".equals(sjklx)) {
                // sqlite
                throw new AppException("暂不支持数据库类型【sqlite】");
            } else if ("4".equals(sjklx)) {
                // oracle
                throw new AppException("暂不支持数据库类型【oracle】");
            } else {
                throw new AppException("暂不支持数据库类型【未知】");
            }
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }
}
